package com.tuni.birthdaymoney.web.controller;

import java.security.Principal;
import java.util.Calendar;
import java.util.Map;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.tuni.birthdaymoney.persistence.entity.Operation;
import com.tuni.birthdaymoney.persistence.entity.Person;
import com.tuni.birthdaymoney.persistence.entity.User;
import com.tuni.birthdaymoney.service.OperationService;
import com.tuni.birthdaymoney.service.PersonService;
import com.tuni.birthdaymoney.service.UserService;
import com.tuni.birthdaymoney.service.util.email.BirthdayUtils;
import com.tuni.birthdaymoney.web.model.MasterPage;
import com.tuni.birthdaymoney.web.model.MoneyBackPage;

@Controller
public class MoneyBackController {

    @Autowired
    private OperationService operationService;
    @Autowired
    private PersonService personService;
    @Autowired
    private UserService userService;

    @RequestMapping(value = "/donations/{receiptorId}/moneyback/{donatorId}", method = RequestMethod.GET)
    public String showMoneyBackPage(Principal principal, @PathVariable("receiptorId") Integer receiptorId,
            @PathVariable("donatorId") Integer donatorId, Map<String, Object> moneyBackPageMap) {
        return showMoneyBack(principal, receiptorId, donatorId, moneyBackPageMap, new MoneyBackPage());
    }

    @RequestMapping(value = "/donations/{receiptorId}/moneyback/{donatorId}/submit", method = RequestMethod.POST)
    public String sumbitMoneyBack(@Valid @ModelAttribute("moneyBackPageModel") MoneyBackPage moneyBackPageModel, BindingResult result,
            @PathVariable("receiptorId") Integer receiptorId, @PathVariable("donatorId") Integer donatorId, Principal principal,
            Map<String, Object> moneyBackPageMap) {
        if (!result.hasErrors()) {
            if (moneyBackPageModel.getOperation().getAmount().doubleValue() < 0) {
                result.rejectValue("operation.amount", "error.user", "Amount should be greater than zero");
                return showMoneyBack(principal, receiptorId, donatorId, moneyBackPageMap, moneyBackPageModel);
            }
            try {
                operationService.saveMoneyBack(moneyBackPageModel.getOperation()); 
            }
            catch (IllegalArgumentException e) {
                result.rejectValue("operation.amount", "error.user", e.getMessage());
                return showMoneyBack(principal, receiptorId, donatorId, moneyBackPageMap, moneyBackPageModel);
            }
            return String.format("redirect:/donations/%s.html", receiptorId);
        }
        return showMoneyBack(principal, receiptorId, donatorId, moneyBackPageMap, moneyBackPageModel);
    }

    private String showMoneyBack(Principal principal, @PathVariable("receiptorId") Integer receiptorId,
            @PathVariable("donatorId") Integer donatorId, Map<String, Object> moneyBackPageMap, MoneyBackPage moneyBackPageModel) {
        User hr_user = userService.getUserByEmail(principal.getName());
        Person hr_person = hr_user.getPerson();
        Person receiptor = personService.getById(receiptorId);

        MasterPage masterPageModel = new MasterPage(hr_user, false);
        moneyBackPageMap.put("masterPageModel", masterPageModel);

        if (receiptor != null && moneyBackPageModel != null) {
            moneyBackPageModel.setDonator(operationService.getDonatorById(receiptor, donatorId));
            if (moneyBackPageModel.getOperation() == null) {
                moneyBackPageModel.setOperation(new Operation());
                moneyBackPageModel.getOperation().setYear(
                        BirthdayUtils.getNextBirthday(receiptor.getBirthday().toGregorianCalendar(), Calendar.getInstance()).get(
                                Calendar.YEAR));
            }
            // update foreign key connected entities
            moneyBackPageModel.getOperation().setReceiptor(receiptor);
            moneyBackPageModel.getOperation().setDonator(personService.getById(donatorId));
            moneyBackPageModel.getOperation().setHumanResources(hr_person);

            moneyBackPageMap.put("moneyBackPageModel", moneyBackPageModel);
            return "moneyback";
        } else {
            // TODO: process error here
            return "redirect:/home.html";
        }
    }
}
